package com.springboot.service.wangyi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.springboot.dao.CommentDao;
import com.springboot.dao.MusicDao;
import com.springboot.entity.CommentEntity;
import com.springboot.entity.MusicEntity;
import com.springboot.util.time.MyDateUtil;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;

import jakarta.annotation.Resource;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName NetEaseMusicPageProcessor
 * @Description
 * @Author zyj
 * @Date 2022/7/7 15:41
 * @Version 1.0
 **/
@Component
public class NetEaseMusicPageProcessor implements PageProcessor {

    @Resource
    private CommentDao commentDao;

    @Resource
    private MusicDao musicDao;

    public static final int ONE_PAGE = 200;

    // 正则表达式\\. \\转义java中的\ \.转义正则中的.
    // 主域名
    public static final String BASE_URL = "http://music.163.com/";
    // 匹配专辑URL
    public static final String ALBUM_URL = "http://music\\.163\\.com/playlist\\?id=\\d+";
    // 匹配歌曲URL
    public static final String MUSIC_URL = "http://music\\.163\\.com/song\\?id=\\d+";

    @Override
    public void process(Page page) {
        // 根据URL判断页面类型
        if (page.getUrl().regex(ALBUM_URL).match()) {
            System.out.println("歌曲总数----->" + page.getHtml().xpath("//span[@id='playlist-track-count']/text()").toString());
            // 爬取歌曲URl加入队列
            page.addTargetRequests(page.getHtml().xpath("//div[@id=\"song-list-pre-cache\"]").links().regex(MUSIC_URL).all());
        } else {
            String url = page.getUrl().toString();
            MusicEntity music = new MusicEntity();
            // 单独对AJAX请求获取评论数, 使用JSON解析返回结果
            String songId = url.substring(url.indexOf("id=") + 3);
            int commentCount = getComment(songId, 0);
            // music 保存到数据库
            music.setSongId(songId);
            music.setCommentCount(commentCount);
            music.setTitle(page.getHtml().xpath("//em[@class='f-ff2']/text()").toString());
            music.setAuthor(page.getHtml().xpath("//p[@class='des s-fc4']/span/a/text()").toString());
            music.setAlbum(page.getHtml().xpath("//p[@class='des s-fc4']/a/text()").toString());
            music.setUrl(url);
            if (musicDao.countBySongId(music.getSongId()) == 0) {
                musicDao.insert(music);
            }
        }
    }

    @Override
    public Site getSite() {
        Site site = Site.me()
                .setDomain("http://music.163.com")
                .setSleepTime(1000)
                .setRetryTimes(30)
                .setCharset("utf-8")
                .setTimeOut(30000)
        //.addHeader("host","k1395252x8.zicp.fun:30449")
        //.addHeader("Proxy-Authorization", "103.46.128.49:30449")
        //.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36 Edg/103.0.1264.37")
        ;
        return site;
    }


    private int getComment(String songId, int offset) {
        int commentCount;
        String s = NetEaseMusicUtils.crawlAjaxUrl(songId, offset);

        if (s.contains("503 Service Temporarily Unavailable")) {
            commentCount = -1;
        } else {
            JSONObject jsonObject = JSON.parseObject(s);
            commentCount = (Integer) JSONPath.eval(jsonObject, "$.total");
            for (; offset < commentCount; offset = offset + ONE_PAGE) {
                JSONObject obj = JSON.parseObject(NetEaseMusicUtils.crawlAjaxUrl(songId, offset));
                List<Long> commentIds = (List<Long>) JSONPath.eval(obj, "$.comments.commentId");
                List<String> contents = (List<String>) JSONPath.eval(obj, "$.comments.content");
                List<Integer> likedCounts = (List<Integer>) JSONPath.eval(obj, "$.comments.likedCount");
                List<String> nicknames = (List<String>) JSONPath.eval(obj, "$.comments.user.nickname");
                List<Long> times = (List<Long>) JSONPath.eval(obj, "$.comments.time");
                List<CommentEntity> comments = new ArrayList<>();
                for (int i = 0; i < contents.size(); i++) {
                    try {
                        // 保存到数据库
                        CommentEntity comment = new CommentEntity();
                        comment.setCommentId(commentIds.get(i).intValue());
                        comment.setSongId(songId);
                        comment.setContent(NetEaseMusicUtils.filterEmoji(contents.get(i)));
                        comment.setLikedCount(likedCounts.get(i));
                        comment.setNickname(nicknames.get(i));
                        comment.setTime(MyDateUtil.coverSqlDatesStr(NetEaseMusicUtils.stampToDate(times.get(i))));
                        comments.add(comment);
                        commentDao.insert(comment);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        return commentCount;
    }
}
